package com.mvvm.library.permission;

/**
 * @创建时间：2023/2/27
 * @作者：小蔡
 * @功能介绍：
 */
import java.util.List;

import io.reactivex.Observable;
import io.reactivex.functions.BiConsumer;
import io.reactivex.functions.Function;
import io.reactivex.functions.Predicate;

public class Permission {
    public final String name;
    public final boolean granted;
    public final boolean shouldShowRequestPermissionRationale;

    public Permission(String name, boolean granted) {
        this(name, granted, false);
    }

    public Permission(String name, boolean granted, boolean shouldShowRequestPermissionRationale) {
        this.name = name;
        this.granted = granted;
        this.shouldShowRequestPermissionRationale = shouldShowRequestPermissionRationale;
    }

    public Permission(List<Permission> permissions) {
        name = combineName(permissions);
        granted = combineGranted(permissions);
        shouldShowRequestPermissionRationale = combineShouldShowRequestPermissionRationale(permissions);
    }

    @Override
    @SuppressWarnings("SimplifiableIfStatement")
    public boolean equals(final Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        final Permission that = (Permission) o;

        if (granted != that.granted) {
            return false;
        }
        if (shouldShowRequestPermissionRationale != that.shouldShowRequestPermissionRationale) {
            return false;
        }
        return name.equals(that.name);
    }

    @Override
    public int hashCode() {
        int result = name.hashCode();
        result = 31 * result + (granted ? 1 : 0);
        result = 31 * result + (shouldShowRequestPermissionRationale ? 1 : 0);
        return result;
    }

    @Override
    public String toString() {
        return "Permission{"
                + "name='"
                + name
                + '\''
                + ", granted="
                + granted
                + ", shouldShowRequestPermissionRationale="
                + shouldShowRequestPermissionRationale
                + '}';
    }

    private String combineName(List<Permission> permissions) {
        return Observable.fromIterable(permissions)
                .map(
                        new Function<Permission, String >() {
                            @Override
                            public String apply(Permission permission) throws Exception {
                                return permission.name;
                            }
                        })
                .collectInto(
                        new StringBuilder(),
                        new BiConsumer< StringBuilder, String >() {
                            @Override
                            public void accept(StringBuilder s, String s2) throws Exception {
                                if (s.length() == 0) {
                                    s.append(s2);
                                } else {
                                    s.append(", ").append(s2);
                                }
                            }
                        })
                .blockingGet()
                .toString();
    }

    private Boolean combineGranted(List<Permission> permissions) {
        return Observable.fromIterable(permissions)
                .all(
                        new Predicate<Permission>() {
                            @Override
                            public boolean test(Permission permission) throws Exception {
                                return permission.granted;
                            }
                        })
                .blockingGet();
    }

    private Boolean combineShouldShowRequestPermissionRationale(List<Permission> permissions) {
        return Observable.fromIterable(permissions)
                .any(
                        new Predicate<Permission>() {
                            @Override
                            public boolean test(Permission permission) throws Exception {
                                return permission.shouldShowRequestPermissionRationale;
                            }
                        })
                .blockingGet();
    }
}